package com.pxmeta.circle.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.pxmeta.circle.entity.CirclePrivilege;
import com.pxmeta.circle.enums.UserTypeEnum;
import com.pxmeta.circle.mapper.CirclePrivilegeMapper;
import com.pxmeta.circle.service.ICirclePrivilegeService;
import com.pxmeta.common.exception.ServiceException;
import com.pxmeta.privilege.entity.Privilege;
import com.pxmeta.privilege.entity.vo.PrivilegeItemVO;
import com.pxmeta.privilege.entity.vo.PrivilegeVO;
import com.pxmeta.privilege.service.IPrivilegeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wcl
 * @since 2022-07-02
 */
@Service
@RequiredArgsConstructor
public class CirclePrivilegeServiceImpl extends ServiceImpl<CirclePrivilegeMapper, CirclePrivilege> implements ICirclePrivilegeService {


    private final IPrivilegeService privilegeService;

    //1通用权限，2成员管理，3聊天权限，4高级权限
    private final static Integer PRIVILEGE_TYPE_COMMON = 1;
    private final static Integer PRIVILEGE_TYPE_MANAGER = 2;
    private final static Integer PRIVILEGE_TYPE_CHAT = 3;
    private final static Integer PRIVILEGE_TYPE_HIGH = 4;

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void initCirclePrivilege(Long circleId) {
        List<Privilege> list = privilegeService.list();
        LinkedList<CirclePrivilege> cpList = Lists.newLinkedList();
        for (Privilege privilege : list) {
            CirclePrivilege adminCp = createCirclePrivilegeByType(privilege, UserTypeEnum.ADMIN);
            adminCp.setCircleId(circleId);
            CirclePrivilege normalCp = createCirclePrivilegeByType(privilege, UserTypeEnum.NORMAL);
            normalCp.setCircleId(circleId);
            cpList.add(adminCp);
            cpList.add(normalCp);
        }
        this.saveBatch(cpList);
    }

    /**
     * 获取圈子当前权限的状态
     * @param circleId
     * @param privilegeId
     * @param type
     * @return
     */
    @Override
    public Integer getPrivilegeStatus(Long circleId, Long privilegeId, Integer type) {
        LambdaQueryWrapper<CirclePrivilege> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CirclePrivilege::getCircleId, circleId)
                .eq(CirclePrivilege::getPrivilegeId, privilegeId)
                .eq(CirclePrivilege::getUserType, type);
        CirclePrivilege cp = this.getOne(wrapper);
        return cp == null? 0 : cp.getStatus();
    }

    @Override
    public PrivilegeVO getCirclePrivilege(Long circleId, Integer type) {
        List<Privilege> list = privilegeService.list();
        PrivilegeVO vo = new PrivilegeVO();
        vo.setCommonPrivilege(listItemByCircle(list, circleId, type, PRIVILEGE_TYPE_COMMON));
        vo.setManagerPrivilege(listItemByCircle(list, circleId, type, PRIVILEGE_TYPE_MANAGER));
        vo.setChatPrivilege(listItemByCircle(list, circleId, type, PRIVILEGE_TYPE_CHAT));
        vo.setHighPrivilege(listItemByCircle(list, circleId, type, PRIVILEGE_TYPE_HIGH));
        return vo;
    }

    @Override
    public List<CirclePrivilege> listByCircleId(List<Long> circleIds) {
        LambdaQueryWrapper<CirclePrivilege> wrapper = Wrappers.lambdaQuery();
        wrapper.in(CirclePrivilege::getCircleId,circleIds);
        return this.list(wrapper);
    }


    private List<PrivilegeItemVO> listItemByCircle(List<Privilege> list, Long circleId, Integer userType, Integer privilegeType){
        return list.stream().filter(l -> privilegeType.equals(l.getType())).map(p->{
            PrivilegeItemVO item = new PrivilegeItemVO();
            String name = p.getName();
            item.setName(name);
            String description = p.getDescription();
            item.setDescription(description);
            item.setId(p.getId());
            Integer status = this.getPrivilegeStatus(circleId,p.getId(),userType);
            item.setStatus(status);
            return item;
        }).collect(Collectors.toList());
    }

    private CirclePrivilege createCirclePrivilegeByType(Privilege privilege, UserTypeEnum type){
        CirclePrivilege cp = new CirclePrivilege();
        cp.setPrivilegeId(privilege.getId());
        cp.setCode(privilege.getCode());
        cp.setUserType(type.getType());
        if (privilege.getType()!=4){
            cp.setStatus(1);
        }else {
            cp.setStatus(0);
        }
        return cp;
    }
}
